package com.scrx.ymg.dao.user;
// default package

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.hibernate.LockOptions;
import org.hibernate.Query;
import org.hibernate.criterion.Example;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import com.scrx.ymg.dao.base.BaseDaoImpl;
import com.scrx.ymg.entity.AgentDrawings;
import com.scrx.ymg.entity.Distribution;
import com.scrx.ymg.entity.User;
import com.scrx.ymg.util.LatLonUtil;

/**
 	* A data access object (DAO) providing persistence and search support for User entities.
 			* Transaction control of the save(), update() and delete() operations 
		can directly support Spring container-managed transactions or they can be augmented	to handle user-managed Spring transactions. 
		Each of these methods provides additional information for how to configure it for the desired type of transaction control. 	
	 * @see .User
  * @author MyEclipse Persistence Tools 
 */

@Repository("userDAO")
@Transactional
public class UserDAOImpl extends BaseDaoImpl implements IUserDao{
    	
    	
    	
	private static final Logger log = LoggerFactory.getLogger(UserDAOImpl.class);
		//property constants
	public static final String USER_NAME = "userName";
	public static final String PASS_WORD = "passWord";
	public static final String ID_CARD = "idCard";
	public static final String LOCATION_ADD = "locationAdd";
	public static final String EXPRESSAGE_ADD = "expressageAdd";
	public static final String LONGITUDE_NUM = "longitudeNum";
	public static final String LATITUDE_NUM = "latitudeNum";

    public void save(User transientInstance) {
        log.debug("saving User instance");
        try {
            getCurrentSession().save(transientInstance);
            log.debug("save successful");
        } catch (RuntimeException re) {
            log.error("save failed", re);
            throw re;
        }
    }
    public User saveGetUserID(User transientInstance) {
        log.debug("saving User instance");
        try {
            getCurrentSession().save(transientInstance);
            return transientInstance;
        } catch (RuntimeException re) {
            log.error("save failed", re);
            throw re;
        }
        
    }
    public List<User> hello(){
    	 List<User> list;
    	 try {
    		 Query queryObject=getCurrentSession().createQuery("from User");
    		 list=queryObject.list();
             log.debug("save successful");
         } catch (RuntimeException re) {
             log.error("save failed", re);
             throw re;
         }
    	 
		return list;
	}
	public void delete(User persistentInstance) {
        log.debug("deleting User instance");
        try {
            getCurrentSession().delete(persistentInstance);
            log.debug("delete successful");
        } catch (RuntimeException re) {
            log.error("delete failed", re);
            throw re;
        }
    }
    
    public User findById(Integer id) {
        log.debug("getting User instance with id: " + id);
        Query queryObject=getCurrentSession().createQuery("from User where id=?");
        queryObject.setParameter(0, id);
        User user=null;
        if(queryObject.list().size()>0){
        	 user=(User)queryObject.list().get(0);
        }
           return user;
    }
    
    
    public List findByExample(User instance) {
        log.debug("finding User instance by example");
        try {
            List results = getCurrentSession().createCriteria("User") .add(Example.create(instance)).list();
            log.debug("find by example successful, result size: " + results.size());
            return results;
        } catch (RuntimeException re) {
            log.error("find by example failed", re);
            throw re;
        }
    }    
    
    public List findByProperty(String propertyName, Object value) {
      log.debug("finding User instance with property: " + propertyName
            + ", value: " + value);
      try {
         String queryString = "from User as model where model." 
         						+ propertyName + "= ?";
         Query queryObject = getCurrentSession().createQuery(queryString);
		 queryObject.setParameter(0, value);
		 return queryObject.list();
      } catch (RuntimeException re) {
         log.error("find by property name failed", re);
         throw re;
      }
	}

	public List findByUserName(Object userName
	) {
		return findByProperty(USER_NAME, userName
		);
	}

	public List findByIdCard(Object idCard
	) {
		return findByProperty(ID_CARD, idCard
		);
	}
	
	public List findByLocationAdd(Object locationAdd
	) {
		return findByProperty(LOCATION_ADD, locationAdd
		);
	}
	
	public List findByExpressageAdd(Object expressageAdd
	) {
		return findByProperty(EXPRESSAGE_ADD, expressageAdd
		);
	}
	
	public List findByLongitudeNum(Object longitudeNum
	) {
		return findByProperty(LONGITUDE_NUM, longitudeNum
		);
	}
	
	public List findByLatitudeNum(Object latitudeNum
	) {
		return findByProperty(LATITUDE_NUM, latitudeNum
		);
	}
	

	public List findAll() {
		log.debug("finding all User instances");
		try {
			String queryString = "from User";
	         Query queryObject = getCurrentSession().createQuery(queryString);
			 return queryObject.list();
		} catch (RuntimeException re) {
			log.error("find all failed", re);
			throw re;
		}
	}
	
    public User merge(User detachedInstance) {
        log.debug("merging User instance");
        try {
            User result = (User) getCurrentSession()
                    .merge(detachedInstance);
            log.debug("merge successful");
            return result;
        } catch (RuntimeException re) {
            log.error("merge failed", re);
            throw re;
        }
    }

    public void attachDirty(User instance) {
        log.debug("attaching dirty User instance");
        try {
            getCurrentSession().saveOrUpdate(instance);
            log.debug("attach successful");
        } catch (RuntimeException re) {
            log.error("attach failed", re);
            throw re;
        }
    }
    
    public void attachClean(User instance) {
        log.debug("attaching clean User instance");
        try {
                      	getCurrentSession().buildLockRequest(LockOptions.NONE).lock(instance);
          	            log.debug("attach successful");
        } catch (RuntimeException re) {
            log.error("attach failed", re);
            throw re;
        }
    }

	public static UserDAOImpl getFromApplicationContext(ApplicationContext ctx) {
    	return (UserDAOImpl) ctx.getBean("UserDAO");
	}

	public User findByUserID(String userid) {
		User user = null;
    	 try {
    		 Query queryObject=getCurrentSession().createQuery("from User where userId=?");
    		 queryObject.setParameter(0, userid);
    		 user=(User)queryObject.uniqueResult();
             log.debug("save successful");
         } catch (RuntimeException re) {
             log.error("save failed", re);
             throw re;
         }
		return user;
	}

	public List<User> getMemberInfoBySuperID(int superId) {
		 Query queryObject=getCurrentSession().createQuery("from User where belongSupermarket=?");
		 queryObject.setParameter(0, superId);
		return (List<User>)queryObject.list();
	}

	
	public Map<Object, Object> getUserInfo(User user, int pageNum, int pageCount) {
		try {
			Map<Object, Object> map = new HashMap<Object, Object>();
			LatLonUtil util = new LatLonUtil();
			StringBuffer hql =new StringBuffer("from User where 1=1 ");
			util.init(user.getAgentId(),"agentId",hql);
			util.init(user.getId(),"id",hql);
			util.init(user.getPhone(),"phone",hql);
			util.init(user.getUserName(),"userName",hql);
			util.init(user.getReferrerId(),"referrerId",hql);
			util.init(user.getBelongSupermarket(),"belongSupermarket",hql);
			Query query=getCurrentSession().createQuery(hql.toString());
			List<User> drawings=query.list();
			query.setMaxResults(pageCount);//每页多少条
			query.setFirstResult((pageNum-1)*pageCount);//第几页
			List<User> drawingslist=query.list();
			map.put("drawingslist", drawingslist);
			map.put("totalMoney", getTotalMoney());
			map.put("userNum", getUserNum());
			map.put("orderNum", getOrderNum());
			map.put("totalVip", drawings.size());
			map.put("totalpage", (drawings.size()+pageCount-1)/pageCount);
            return map;
        } catch (RuntimeException re) {
            log.error("get failed", re);
            throw re;
        }
	}
	public List<User> getUsers(User user, int pageNum, int pageCount) {
		try {
			Map<Object, Object> map = new HashMap<Object, Object>();
			LatLonUtil util = new LatLonUtil();
			StringBuffer hql =new StringBuffer("from User user where 1=1 ");
			util.init(user.getId(),"id",hql);
			util.init(user.getPhone(),"phone",hql);
			util.init(user.getUserName(),"userName",hql);
			util.init(user.getReferrerId(),"referrerId",hql);
			Query query=getCurrentSession().createQuery(hql.toString());
			List<User> drawings=query.list();
			query.setMaxResults(pageCount);//每页多少条
			query.setFirstResult((pageNum-1)*pageCount);//第几页
			List<User> drawingslist=query.list();
			for (int i = 0; i < drawingslist.size(); i++) {
				drawingslist.get(i).setUserId(null);
				drawingslist.get(i).setDownlineNum(getDownlineNumByUserId(drawingslist.get(i).getId()));
			}
            return drawingslist;
        } catch (RuntimeException re) {
            log.error("get failed", re);
            throw re;
        }
	}
	
	/**
	 * 消费者消费总金额
	 * @return
	 */
	public double getTotalMoney(){
		Query	query = getCurrentSession().createQuery("select SUM(consumeMoney) from User");
		Iterator iter = query.iterate();
		double num=0;
		while(iter.hasNext()){
			Object obj =iter.next();
			num=Double.parseDouble(obj.toString());
		};
		return num;
	}
	/**
	 * 消费者总人数
	 * @return
	 */
	public int getUserNum(){
		Query	query = getCurrentSession().createQuery("select count(*) from User");
		Iterator iter = query.iterate();
		int num=0;
		while(iter.hasNext()){
			num=((Long)iter.next()).intValue();
		};
		return num;
	}
	/**
	 * 消费者总人数
	 * @return
	 */
	public int getOrderNum(){
		Query	query = getCurrentSession().createQuery("select SUM(orderNum) from User");
		Iterator iter = query.iterate();
		int num=0;
		while(iter.hasNext()){
			num=((Long)iter.next()).intValue();
		};
		return num;
	}

	public String updateUser(User user) {
		try {
			getCurrentSession().update(user);
			return "true";
		} catch (Exception e) {
			return "false";
		}
	}

	public Integer getDownlineNumByUserId(int userId) {
		Query	query = getCurrentSession().createQuery("select COUNT(*) from User where referrerId=:userId");
		query.setParameter("userId", userId);
		Integer temp=Integer.parseInt(query.uniqueResult().toString());
		return temp;
	}
	public String insertAndUpdateObjects(Object insert, Object update) {
		try {
			getCurrentSession().update(update);
			getCurrentSession().save(insert);
			return "true";
		} catch (Exception e) {
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return "false";
		}
	}
	public String updateObjects(List<Object> objects) {
		try {
			for (int i = 0; i < objects.size(); i++) {
				this.getCurrentSession().update(objects.get(i));
			}
    		return "true";
		} catch (Exception e) {
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return "false";
		}
	}
	public Map<Object, Object> getUserXiaXian(int userId) {
		Map<Object, Object> map=new HashMap<Object, Object>();
		Query	query = getCurrentSession().createQuery("from User where referrerId=:id");
		query.setParameter("id", userId);
		List<User> users=query.list();
		List<User> users2=new ArrayList<User>();
		for (int i = 0; i < users.size(); i++) {
			Query	query2 = getCurrentSession().createQuery("from User where referrerId=:id");
			query2.setParameter("id", users.get(i).getId());
			List<User> temp=query2.list();
			for (int j = 0; j < temp.size(); j++) {
				users2.add(temp.get(j));
			}
		}
		map.put("oneLevel", users);
		map.put("twoLevel", users2);
		map.put("userSize", users.size()+users2.size());
		return map;
	}
}